import csv
import os
import pandas as pd

# --- 1. 生理参数数据 (从表格上半部分解析) ---
all_physiological_parameters = [
    {
        "Name": "Adipose",
        "relative_volume_wet_tissue_EW": 14.1,
        "relative_volume_wet_tissue_IW": 3.9,
        "relative_volume_wet_tissue_NL": 79,
        "relative_volume_wet_tissue_NP": 0.2,
        "relative_volume_wet_tissue_subcellular": 0,
        "AP_mg_g": 0.4,
        "binding_proteins_Kp_ALB": 0.037,
        "binding_proteins_Kp_LPP": 0.068,
        "tissue_volume_fold_scalar_local": 1,
        "tissue_volume_fold_scalar_subcellular": 7,
        "IW_pH": 5,
        "membrane_potential_mV_local": -41,
        "membrane_potential_mV_subcellular": 10,
        "subcompartment_for_biologics_Vv_percent": 3.1,
        "subcompartment_for_biologics_Ve_decimal": 0.039
    },
    {
        "Name": "Bone",
        "relative_volume_wet_tissue_EW": 9.8,
        "relative_volume_wet_tissue_IW": 34.1,
        "relative_volume_wet_tissue_NL": 7.4,
        "relative_volume_wet_tissue_NP": 0.1,
        "relative_volume_wet_tissue_subcellular": 0,
        "AP_mg_g": 0.67,
        "binding_proteins_Kp_ALB": 0.1,
        "binding_proteins_Kp_LPP": 0.05,
        "tissue_volume_fold_scalar_local": 1,
        "tissue_volume_fold_scalar_subcellular": 7,
        "IW_pH": 5,
        "membrane_potential_mV_local": -41,
        "membrane_potential_mV_subcellular": 10,
        "subcompartment_for_biologics_Vv_percent": 5,
        "subcompartment_for_biologics_Ve_decimal": 0.063
    },
    {
        "Name": "Brain",
        "relative_volume_wet_tissue_EW": 9.2,
        "relative_volume_wet_tissue_IW": 67.8,
        "relative_volume_wet_tissue_NL": 5.1,
        "relative_volume_wet_tissue_NP": 5.65,
        "relative_volume_wet_tissue_subcellular": 0,
        "AP_mg_g": 0.4,
        "binding_proteins_Kp_ALB": 0.048,
        "binding_proteins_Kp_LPP": 0.041,
        "tissue_volume_fold_scalar_local": 1,
        "tissue_volume_fold_scalar_subcellular": 7.12,
        "IW_pH": 5,
        "membrane_potential_mV_local": -41,
        "membrane_potential_mV_subcellular": 10,
        "subcompartment_for_biologics_Vv_percent": 5,
        "subcompartment_for_biologics_Ve_decimal": 0.063
    },
    {
        "Name": "Gut",
        "relative_volume_wet_tissue_EW": 26.7,
        "relative_volume_wet_tissue_IW": 45.1,
        "relative_volume_wet_tissue_NL": 4.87,
        "relative_volume_wet_tissue_NP": 1.63,
        "relative_volume_wet_tissue_subcellular": 0,
        "AP_mg_g": 2.84,
        "binding_proteins_Kp_ALB": 0.157,
        "binding_proteins_Kp_LPP": 0.141,
        "tissue_volume_fold_scalar_local": 1,
        "tissue_volume_fold_scalar_subcellular": 7,
        "IW_pH": 5,
        "membrane_potential_mV_local": -41,
        "membrane_potential_mV_subcellular": 10,
        "subcompartment_for_biologics_Vv_percent": 5,
        "subcompartment_for_biologics_Ve_decimal": 0.063
    },
    {
        "Name": "Heart",
        "relative_volume_wet_tissue_EW": 31.3,
        "relative_volume_wet_tissue_IW": 44.5,
        "relative_volume_wet_tissue_NL": 1.15,
        "relative_volume_wet_tissue_NP": 1.66,
        "relative_volume_wet_tissue_subcellular": 0,
        "AP_mg_g": 3.07,
        "binding_proteins_Kp_ALB": 0.157,
        "binding_proteins_Kp_LPP": 0.16,
        "tissue_volume_fold_scalar_local": 1,
        "tissue_volume_fold_scalar_subcellular": 7,
        "IW_pH": 5,
        "membrane_potential_mV_local": -41,
        "membrane_potential_mV_subcellular": 10,
        "subcompartment_for_biologics_Vv_percent": 4.2,
        "subcompartment_for_biologics_Ve_decimal": 0.053
    },
    {
        "Name": "Kidney",
        "relative_volume_wet_tissue_EW": 28.3,
        "relative_volume_wet_tissue_IW": 50,
        "relative_volume_wet_tissue_NL": 2.07,
        "relative_volume_wet_tissue_NP": 1.62,
        "relative_volume_wet_tissue_subcellular": 1,
        "AP_mg_g": 2.48,
        "binding_proteins_Kp_ALB": 0.13,
        "binding_proteins_Kp_LPP": 0.137,
        "tissue_volume_fold_scalar_local": 1,
        "tissue_volume_fold_scalar_subcellular": 7.2,
        "IW_pH": 5,
        "membrane_potential_mV_local": -70,
        "membrane_potential_mV_subcellular": 10,
        "subcompartment_for_biologics_Vv_percent": 7,
        "subcompartment_for_biologics_Ve_decimal": 0.088
    },
    {
        "Name": "Liver",
        "relative_volume_wet_tissue_EW": 15.5,
        "relative_volume_wet_tissue_IW": 58.6,
        "relative_volume_wet_tissue_NL": 3.48,
        "relative_volume_wet_tissue_NP": 2.52,
        "relative_volume_wet_tissue_subcellular": 1,
        "AP_mg_g": 5.09,
        "binding_proteins_Kp_ALB": 0.086,
        "binding_proteins_Kp_LPP": 0.161,
        "tissue_volume_fold_scalar_local": 0.85,
        "tissue_volume_fold_scalar_subcellular": 7,
        "IW_pH": 5,
        "membrane_potential_mV_local": -41,
        "membrane_potential_mV_subcellular": 10,
        "subcompartment_for_biologics_Vv_percent": 5,
        "subcompartment_for_biologics_Ve_decimal": 0.063
    },
    {
        "Name": "Lung",
        "relative_volume_wet_tissue_EW": 34.8,
        "relative_volume_wet_tissue_IW": 46.3,
        "relative_volume_wet_tissue_NL": 0.3,
        "relative_volume_wet_tissue_NP": 0.9,
        "relative_volume_wet_tissue_subcellular": 1,
        "AP_mg_g": 0.5,
        "binding_proteins_Kp_ALB": 0.212,
        "binding_proteins_Kp_LPP": 0.168,
        "tissue_volume_fold_scalar_local": 1,
        "tissue_volume_fold_scalar_subcellular": 6.7,
        "IW_pH": 5,
        "membrane_potential_mV_local": -41,
        "membrane_potential_mV_subcellular": 10,
        "subcompartment_for_biologics_Vv_percent": 18.54,
        "subcompartment_for_biologics_Ve_decimal": 0.232
    },
    {
        "Name": "Muscle",
        "relative_volume_wet_tissue_EW": 9.1,
        "relative_volume_wet_tissue_IW": 66.9,
        "relative_volume_wet_tissue_NL": 2.38,
        "relative_volume_wet_tissue_NP": 0.72,
        "relative_volume_wet_tissue_subcellular": 0,
        "AP_mg_g": 2.49,
        "binding_proteins_Kp_ALB": 0.034,
        "binding_proteins_Kp_LPP": 0.059,
        "tissue_volume_fold_scalar_local": 1,
        "tissue_volume_fold_scalar_subcellular": 7,
        "IW_pH": 55,  # 注意：原始数据就是 55，可能表示某种特殊情况或数据录入方式
        "membrane_potential_mV_local": -41,
        "membrane_potential_mV_subcellular": 10,
        "subcompartment_for_biologics_Vv_percent": 2.7,
        "subcompartment_for_biologics_Ve_decimal": 0.034
    },
    {
        "Name": "Pancreas",
        "relative_volume_wet_tissue_EW": 12,
        "relative_volume_wet_tissue_IW": 66.4,
        "relative_volume_wet_tissue_NL": 4.1,
        "relative_volume_wet_tissue_NP": 0.93,
        "relative_volume_wet_tissue_subcellular": 0,
        "AP_mg_g": 1.67,
        "binding_proteins_Kp_ALB": 0.06,
        "binding_proteins_Kp_LPP": 0.06,
        "tissue_volume_fold_scalar_local": 1,
        "tissue_volume_fold_scalar_subcellular": 7,
        "IW_pH": 5,
        "membrane_potential_mV_local": -41,
        "membrane_potential_mV_subcellular": 10,
        "subcompartment_for_biologics_Vv_percent": 5,
        "subcompartment_for_biologics_Ve_decimal": 0.063
    },
    {
        "Name": "Skin",
        "relative_volume_wet_tissue_EW": 62.3,
        "relative_volume_wet_tissue_IW": 9.47,
        "relative_volume_wet_tissue_NL": 2.84,
        "relative_volume_wet_tissue_NP": 1.11,
        "relative_volume_wet_tissue_subcellular": 0,
        "AP_mg_g": 1.32,
        "binding_proteins_Kp_ALB": 0.277,
        "binding_proteins_Kp_LPP": 0.096,
        "tissue_volume_fold_scalar_local": 1,
        "tissue_volume_fold_scalar_subcellular": 7,
        "IW_pH": 5,
        "membrane_potential_mV_local": -41,
        "membrane_potential_mV_subcellular": 10,
        "subcompartment_for_biologics_Vv_percent": 5,
        "subcompartment_for_biologics_Ve_decimal": 0.063
    },
    {
        "Name": "Spleen",
        "relative_volume_wet_tissue_EW": 20.8,
        "relative_volume_wet_tissue_IW": 57.9,
        "relative_volume_wet_tissue_NL": 2.01,
        "relative_volume_wet_tissue_NP": 1.98,
        "relative_volume_wet_tissue_subcellular": 0,
        "AP_mg_g": 2.81,
        "binding_proteins_Kp_ALB": 0.097,
        "binding_proteins_Kp_LPP": 0.207,
        "tissue_volume_fold_scalar_local": 1,
        "tissue_volume_fold_scalar_subcellular": 7,
        "IW_pH": 5,
        "membrane_potential_mV_local": -41,
        "membrane_potential_mV_subcellular": 10,
        "subcompartment_for_biologics_Vv_percent": 5,
        "subcompartment_for_biologics_Ve_decimal": 0.063
    },
    {
        "Name": "Plasma",
        "relative_volume_wet_tissue_EW": 94.5,
        "relative_volume_wet_tissue_IW": 0,
        "relative_volume_wet_tissue_NL": 0.35,
        "relative_volume_wet_tissue_NP": 0.23,
        "relative_volume_wet_tissue_subcellular": None,  # 原始表格为空
        "AP_mg_g": 0.04,
        "binding_proteins_Kp_ALB": None,  # 原始表格为空
        "binding_proteins_Kp_LPP": None,  # 原始表格为空
        "tissue_volume_fold_scalar_local": 1,
        "tissue_volume_fold_scalar_subcellular": 7.4,  # Plasma 的这个值在原始表格中是 7.4，可能对应其pH
        "IW_pH": None,  # 原始表格为空
        "membrane_potential_mV_local": None,  # 原始表格为空
        "membrane_potential_mV_subcellular": None,  # 原始表格为空
        "subcompartment_for_biologics_Vv_percent": None,  # 原始表格为空
        "subcompartment_for_biologics_Ve_decimal": None  # 原始表格为空
    },
    {
        "Name": "RBC",  # 红细胞
        "relative_volume_wet_tissue_EW": 0,
        "relative_volume_wet_tissue_IW": 66.6,
        "relative_volume_wet_tissue_NL": 0.17,
        "relative_volume_wet_tissue_NP": 0.29,
        "relative_volume_wet_tissue_subcellular": None,  # 原始表格为空
        "AP_mg_g": 0.44,
        "binding_proteins_Kp_ALB": None,  # 原始表格为空
        "binding_proteins_Kp_LPP": None,  # 原始表格为空
        "tissue_volume_fold_scalar_local": 1,
        "tissue_volume_fold_scalar_subcellular": 7.22,  # RBC 的这个值在原始表格中是 7.22，可能对应其pH
        "IW_pH": None,  # 原始表格为空
        "membrane_potential_mV_local": -10,  # 修改为-10
        "membrane_potential_mV_subcellular": None,  # 原始表格为空
        "subcompartment_for_biologics_Vv_percent": None,  # 原始表格为空
        "subcompartment_for_biologics_Ve_decimal": None  # 原始表格为空
    }
]

# --- 2. 局部pH数据 (从表格中部解析) ---
local_pH_data = {
    "Plasma": 7.4,
    "EW": 7.4,
    "IW": 7,
    "Gut ISF": 7.23,
    "IWRBC": 7.22,
    "Pulmonary Fluid": 6.6,
    "Brain ISF": 7.31,
    "Brain ICF": 7.01,
    "CSF": 7.31
}

# --- 3. 器官体积数据 (从表格下半部分解析) ---
organ_volumes_data = [
    {"Organ": "Brain", "Volume_mL": 1450},
    {"Organ": "Liver", "Volume_mL": 1690},
    {"Organ": "Kidneys", "Volume_mL": 280},
    {"Organ": "Heart", "Volume_mL": 310},
    {"Organ": "Spleen", "Volume_mL": 192},
    {"Organ": "Lungs", "Volume_mL": 1170},
    {"Organ": "Gut", "Volume_mL": 1650},
    {"Organ": "Muscle", "Volume_mL": 35000},
    {"Organ": "Adipose", "Volume_mL": 10000},
    {"Organ": "Skin", "Volume_mL": 7800},
    {"Organ": "Blood", "Volume_mL": 5200},
    {"Organ": "Pancreas", "Volume_mL": 73},
    {"Organ": "Plasma", "Volume_mL": 3000},
    {"Organ": "RBC", "Volume_mL": 2200},
    {"Organ": "Bone", "Volume_mL": 5300},
]

# 读取Kidney脚本输出的肾体积并替换
try:
    kidney_volume_df = pd.read_csv('kidney_volume.csv')
    kidney_volume_mean = kidney_volume_df['Volume_kidney_mL'].mean()
    for organ in organ_volumes_data:
        if organ['Organ'] == 'Kidneys':
            organ['Volume_mL'] = kidney_volume_mean
    print(f"已用kidney_volume.csv中的均值({kidney_volume_mean:.2f} mL)替换Kidneys体积")
except Exception as e:
    print(f"未能读取kidney_volume.csv，继续使用默认Kidneys体积。原因: {e}")

# 输出目录
OUTPUT_DIR = r"C:/Users/27135/Desktop/population/Tissue composition/"
os.makedirs(OUTPUT_DIR, exist_ok=True)

def format_key_for_display(key):
    """Helper to format dictionary keys into readable strings for CSV headers."""
    return key.replace('_', ' ').replace('wet tissue', 'Wet Tissue') \
        .replace('AP mg g', 'AP (mg/g)') \
        .replace('Kp ALB', 'Kp,ALB') \
        .replace('Kp LPP', 'Kp,LPP') \
        .replace('fold scalar', 'Fold Scalar') \
        .replace('mV local', ' (Local, mV)') \
        .replace('mV subcellular', ' (Subcellular, mV)') \
        .replace('Vv percent', 'Vv (%)') \
        .replace('Ve decimal', 'Ve (decimal)') \
        .replace('subcompartment for biologics', 'Subcompartment for Biologics') \
        .title()


def export_parameters_one_per_row(parameters, organ_volumes, filename="parameters_one_per_row.csv"):
    """
    每行一个参数，三列：Organ, Parameter Name, Value（含绝对体积参数）
    """
    relative_keys = [
        "relative_volume_wet_tissue_EW",
        "relative_volume_wet_tissue_IW",
        "relative_volume_wet_tissue_NL",
        "relative_volume_wet_tissue_NP",
        "relative_volume_wet_tissue_subcellular"
    ]
    organ_volume_map = {o["Organ"]: o["Volume_mL"] for o in organ_volumes}
    kidney_volume = organ_volume_map.get("Kidneys")
    lung_volume = organ_volume_map.get("Lungs")
    plasma_volume = organ_volume_map.get("Plasma")
    rbc_volume = organ_volume_map.get("RBC")
    processed = []
    for organ in parameters:
        row = dict(organ)
        name = organ.get("Name")
        # 对Kidney、Lung、Plasma、RBC单独处理
        if name == "Kidney" and kidney_volume is not None:
            for key in relative_keys:
                rel_val = organ.get(key)
                abs_key = key.replace("relative_volume_wet_tissue_", "") + "_absolute_volume"
                if rel_val is not None:
                    row[abs_key] = kidney_volume * rel_val / 100
                else:
                    row[abs_key] = None
        elif name == "Lung" and lung_volume is not None:
            for key in relative_keys:
                rel_val = organ.get(key)
                abs_key = key.replace("relative_volume_wet_tissue_", "") + "_absolute_volume"
                if rel_val is not None:
                    row[abs_key] = lung_volume * rel_val / 100
                else:
                    row[abs_key] = None
        elif name == "Plasma" and plasma_volume is not None:
            for key in relative_keys:
                rel_val = organ.get(key)
                abs_key = key.replace("relative_volume_wet_tissue_", "") + "_absolute_volume"
                if rel_val is not None:
                    row[abs_key] = plasma_volume * rel_val / 100
                else:
                    row[abs_key] = None
        elif name == "RBC" and rbc_volume is not None:
            for key in relative_keys:
                rel_val = organ.get(key)
                abs_key = key.replace("relative_volume_wet_tissue_", "") + "_absolute_volume"
                if rel_val is not None:
                    row[abs_key] = rbc_volume * rel_val / 100
                else:
                    row[abs_key] = None
        else:
            total_volume = organ_volume_map.get(name)
            if total_volume is not None:
                for key in relative_keys:
                    rel_val = organ.get(key)
                    abs_key = key.replace("relative_volume_wet_tissue_", "") + "_absolute_volume"
                    if rel_val is not None:
                        row[abs_key] = total_volume * rel_val / 100
                    else:
                        row[abs_key] = None
            else:
                for key in relative_keys:
                    abs_key = key.replace("relative_volume_wet_tissue_", "") + "_absolute_volume"
                    row[abs_key] = None
        processed.append(row)
    # 输出
    filepath = os.path.join(OUTPUT_DIR, filename)
    with open(filepath, 'w', newline='', encoding='utf-8') as csvfile:
        writer = csv.writer(csvfile)
        writer.writerow(['Organ', 'Parameter Name', 'Value'])
        for organ in processed:
            organ_name = organ.get('Name', 'Unknown')
            for key, value in organ.items():
                if key == 'Name':
                    continue
                writer.writerow([organ_name, key, value if value is not None else 'N/A'])
    print(f"所有参数已成功输出到 '{filepath}'，每行一个参数。")

def generate_tissue_composition_parameters_from_df(df):
    """
    批量生成组织成分参数，输入人口学DataFrame，输出每个人每个器官的参数（带id），所有参数均用all_physiological_parameters中的均值。
    """
    results = []
    for idx, row in df.iterrows():
        person_id = row.get('id', idx)
        for organ in all_physiological_parameters:
            organ_row = {'id': person_id, 'Organ': organ.get('Name', 'Unknown')}
            for k, v in organ.items():
                if k == 'Name':
                    continue
                organ_row[k] = v
            results.append(organ_row)
    return pd.DataFrame(results)

def tissue_composition_long_to_wide(df, total_df=None):
    """
    将组织成分长表（每个人每器官一行）转换为宽表（每个人一行，每个器官的EW/IW为单独字段），并输出绝对体积。
    字段命名格式：器官名_参数名（如Liver_EW_absolute_volume）。
    对于Liver和Kidney，优先用主表中的个体化体积，其它器官用organ_volumes_data默认体积。Lung一律用organ_volumes_data默认体积。
    """
    keep_cols = ['id', 'Organ', 'relative_volume_wet_tissue_EW', 'relative_volume_wet_tissue_IW']
    df = df[keep_cols]
    organ_volume_map = {o["Organ"]: o["Volume_mL"] for o in organ_volumes_data}
    # 生成宽表（相对体积）
    wide = df.pivot(index='id', columns='Organ')
    # 字段名格式：器官名_参数名
    wide.columns = [f"{organ}_{param}" for param, organ in wide.columns]
    wide = wide.reset_index()
    # 计算绝对体积
    abs_cols = {}
    for organ in df['Organ'].unique():
        ew_col = f'{organ}_relative_volume_wet_tissue_EW'
        iw_col = f'{organ}_relative_volume_wet_tissue_IW'
        if organ == 'Liver':
            if total_df is not None and 'Liver_Volume_L' in total_df.columns:
                abs_vol = total_df.set_index('id')['Liver_Volume_L'] * 1000
            else:
                abs_vol = organ_volume_map.get('Liver', 0)
        elif organ == 'Kidney':
            if total_df is not None and 'Volume_kidney_mL' in total_df.columns:
                abs_vol = total_df.set_index('id')['Volume_kidney_mL']
            else:
                abs_vol = organ_volume_map.get('Kidneys', 0)
        else:
            abs_vol = organ_volume_map.get(organ, 0)
        if isinstance(abs_vol, pd.Series):
            abs_cols[f'{organ}_EW_absolute_volume'] = wide[ew_col] * abs_vol / 100
            abs_cols[f'{organ}_IW_absolute_volume'] = wide[iw_col] * abs_vol / 100
        else:
            abs_cols[f'{organ}_EW_absolute_volume'] = wide[ew_col] * abs_vol / 100
            abs_cols[f'{organ}_IW_absolute_volume'] = wide[iw_col] * abs_vol / 100
    for k, v in abs_cols.items():
        wide[k] = v.values if hasattr(v, 'values') else v
    return wide

# --- 执行导出 ---
if __name__ == "__main__":
    print("开始导出数据到CSV文件...")
    export_parameters_one_per_row(all_physiological_parameters, organ_volumes_data)
    print("所有数据导出完成。") 